package com.examsys.util;

import java.io.Reader;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * 数据库工具类，用于打开连接，关闭资源等
 * 
 * @author Oracle
 * 
 */
public class DBUtil {

	private static final ThreadLocal threadLocal = new ThreadLocal();// 存放数据库连接的线程池

	private static SqlSessionFactory factory;
	static {
		String mydatisXml = "MyBatis.xml";
		Reader reader = null;
		try {
			reader = Resources.getResourceAsReader(mydatisXml);
		} catch (Exception e) {
			e.printStackTrace();
		}

		factory = new SqlSessionFactoryBuilder().build(reader);

	}

	// 每次收到请求，获取一个会话来操作数据库
	public static synchronized SqlSession getSession() throws Exception{
		
		SqlSession session = (SqlSession) threadLocal.get();// 从线程池中拿出数据库连接对象
		try {
			if (session == null) {// 如果没有拿到数据库连接对象,则打开一个新的连接供使用
				session = factory.openSession();
				threadLocal.set(session);// 把打开的连接对象存放线程池中，供下次使用省掉创建连接的时间
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("数据库访问失败..");
		}
		return session;
	}

	

	/**
	 * 关掉数据库连接对象
	 * 
	 * @throws Exception
	 */
	public static void closeSession() throws Exception {
		SqlSession session = (SqlSession) threadLocal.get();// 从线程池中拿出数据库连接对象
		if (session != null) {// 如果拿到数据库连接对象,则关闭连接
			try {
				session.close();// 关闭连接
			} catch (Exception e) {
				throw new Exception("关闭数据库连接失败..");
			}
			threadLocal.set(null);// 从线程池中清掉此数据库连接对象
		}
	}

	/**
	 * 提交事务的方法
	 * 
	 * @throws Exception
	 */
	public static void commit() throws Exception {
		getSession().commit();// 提交事务
	}

	/**
	 * 回滚事务的方法
	 */
	public static void rollback() {
		try {
			getSession().rollback();// 回滚事务的方法
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 关掉数据集对象，释放资源
	 * 
	 * @param rs
	 */
	public static void close(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();// 关掉数据集对象，释放资源
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}
